package cn.xinfei.xdecision.engine.runner.service;

import cn.xinfei.xdecision.common.utils.util.LocalDateUtils;
import cn.xinfei.xdecision.common.utils.util.SerialNumberUtils;
import cn.xinfei.xdecision.constant.GlobalConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;


@Slf4j
@Service
public class DecisionIdBuilder {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    private static final String INCR = "INCR";

    /**
     * 两天的毫秒数
     */
    private static final Long TWO_DAY=172800000L;

    /**
     * 临时兜底计数器
     * 针对不同场景会出现跳数的情况
     */
    private static volatile AtomicLong counter=new AtomicLong(0);

    public String create(String scene) {
        if (StringUtils.isEmpty(scene)) {
            scene = "DEFAULT";
        }
        String todayNow = LocalDateUtils.getTodayNow(LocalDateUtils.DATE_SIMPLE_PATTERN);
        String flag = INCR + scene + todayNow;
        Long todayInc = getIndex(flag);
        String decisionId = SerialNumberUtils.create(scene, todayInc);
        MDC.put(GlobalConstant.PID, decisionId);
        return decisionId;
    }

    public Long getIndex(String flag){
        try {
            long todayInc = stringRedisTemplate.opsForValue().increment(flag);
            stringRedisTemplate.expire(flag,TWO_DAY, TimeUnit.MILLISECONDS);
            //不区分场景，天数，统一计数
            counter.incrementAndGet();
            return todayInc;
        }catch (Exception e){
            log.error("基于redis的计数器发生异常，flag={},fail={}",flag,e.getMessage(),e);
        }
        return counter.incrementAndGet();
    }
}
